﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Migracion.Data.PeOnline;


namespace Migracion.Process
{
    public class IdentityTranslationManager
    {
        public bool modoProduccion = false;

        public const string tJurisFallo = "tJurisFallo";
        public const string tTribunal = "tTribunal";
        public const string tMinistro = "tMinistro";
        public const string tProducto = "tProducto";
        public const string tTipoVoto = "tTipoVoto";
        public const string tAutor = "tAutor";
        public const string tTipoDoc = "tTipoDoc";
        public const string tEditorial = "tEditorial";
        public const string tMateria = "tMateria";
        public const string tDoctrinaSumario = "tDoctrinaSumario";
        public const string tObraCuerpo = "tObraCuerpo";
        public const string tObra = "tObra";
        public const string tJurisSumario = "tJurisSumario";
        public const string tPublicacionFallo = "tPublicacionFallo";
        public const string tLegislacion = "tLegislacion";
        public const string tLegislacionPartes = "tLegislacionPartes";
        public const string tLegislacionCuerpo = "tLegislacionCuerpo";
        public const string tSentencia = "tSentencia";
        public const string jurisdiccion = "jurisdiccion";
        public const string imagen = "imagen";
        public const string tiposNorma = "TiposNorma";
        public const string tOrganismo = "tOrganismo";

        public const string separadorCache = "$$";

        private HttpRuntime runtime = new HttpRuntime();
        private TimeSpan slidingSpiration = new TimeSpan(0, 5, 0);

        public Guid GetGuidIdForApEntity(string entity, int id)
        {
            string cacheKey = entity + "i" + id.ToString();

            Guid? guidSae = GetGuidFromCache(entity, cacheKey);
            if (guidSae.HasValue)
            {
                return guidSae.Value;
            }
            else
            {
                using (PE_ONLINE_PRODUCCIONEntities ctxPeOnline = new PE_ONLINE_PRODUCCIONEntities())
                {
                    MigracionIds migracionId = ctxPeOnline.MigracionIds.Where(m => m.NombreTabla == entity && m.IdApInt == id).SingleOrDefault();
                    if (migracionId == null)
                    {
                        // Si es nulo lo creo
                        if (PuedoCrearEntity(entity, id.ToString()))
                        {
                            migracionId = new MigracionIds();
                            migracionId.NombreTabla = entity;
                            migracionId.IdApInt = id;
                            migracionId.IdSAEGuid = Guid.NewGuid();
                            ctxPeOnline.MigracionIds.AddObject(migracionId);
                            ctxPeOnline.SaveChanges();
                        }
                    }

                    StoreGuidInCache(entity, cacheKey, migracionId.IdSAEGuid.Value);

                    return migracionId.IdSAEGuid.Value;
                }
            }
        }

        public int GetApIntFromList(string entity, List<int> ids)
        {
            int returnVAlue = 0;
            foreach (var id in ids)
            {
                string cacheKey = entity + "i" + id.ToString();
                Guid? guidSae = GetGuidFromCache(entity, cacheKey);
                if (guidSae.HasValue)
                {
                    returnVAlue = id;
                    break;
                }
            }

            if (returnVAlue == 0)
            {
                // Lo busco en la base
                foreach (var id in ids)
                {
                    MigracionIds migracionId;
                    using (PE_ONLINE_PRODUCCIONEntities ctxPeOnline = new PE_ONLINE_PRODUCCIONEntities())
                    {
                        migracionId = ctxPeOnline.MigracionIds.Where(m => m.NombreTabla == entity && m.IdApInt == id).SingleOrDefault();
                        if (migracionId != null)
                        {
                            returnVAlue = id;
                            break;
                        }

                    }
                }
            }

            return returnVAlue;
        }

        private Guid? GetGuidFromCache(string entity, string cacheKey)
        {
            Guid? guid = null;
            if (!(entity != tLegislacion &&
                  entity != tJurisSumario &&
                   entity != tJurisFallo &&
                   entity != tDoctrinaSumario &&
                   entity != tObraCuerpo &&
                   entity != tObra)
                   )
            {
                guid = (Guid?)HttpRuntime.Cache.Get(cacheKey);
            }

            return guid;
        }

        private void StoreGuidInCache(string entity, string cacheKey, Guid guid)
        {
            if (!(entity != tLegislacion &&
                  entity != tJurisSumario &&
                   entity != tJurisFallo &&
                   entity != tDoctrinaSumario &&
                   entity != tObraCuerpo &&
                   entity != tObra)
                   )
            {
                HttpRuntime.Cache.Add(cacheKey, guid, null, System.Web.Caching.Cache.NoAbsoluteExpiration, slidingSpiration, System.Web.Caching.CacheItemPriority.Normal, null);
            }
        }

        /// <summary>
        /// Para las materias, el mapeo es múltiple
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<Guid> GetGuidListIdForApEntity(string entity, int id)
        {
            using (PE_ONLINE_PRODUCCIONEntities ctxPeOnline = new PE_ONLINE_PRODUCCIONEntities())
            {
                List<MigracionIds> migracionIdList = ctxPeOnline.MigracionIds.Where(m => m.NombreTabla == entity && m.IdApInt == id).ToList();
                if (migracionIdList.Count() == 0)
                {
                    // Si es nulo lo creo
                    if (PuedoCrearEntity(entity, id.ToString()))
                    {
                        MigracionIds migracionId = new MigracionIds();
                        migracionId.NombreTabla = entity;
                        migracionId.IdApInt = id;
                        migracionId.IdSAEGuid = Guid.NewGuid();
                        ctxPeOnline.MigracionIds.AddObject(migracionId);
                        ctxPeOnline.SaveChanges();
                    }
                }

                return migracionIdList.Select(m => m.IdSAEGuid.Value).ToList();
            }
        }

        public Guid GetGuidIdForApEntity(string entity, string id)
        {
            string cacheKey = entity + "s" + id.ToString();

            Guid? guidSae = GetGuidFromCache(entity, cacheKey);
            if (guidSae.HasValue)
            {
                return guidSae.Value;
            }
            else
            {
                using (PE_ONLINE_PRODUCCIONEntities ctxPeOnline = new PE_ONLINE_PRODUCCIONEntities())
                {
                    MigracionIds migracionId = ctxPeOnline.MigracionIds.Where(m => m.NombreTabla == entity && m.IdApStr == id).SingleOrDefault();
                    if (migracionId == null)
                    {
                        // Si es nulo lo creo
                        if (PuedoCrearEntity(entity, id))
                        {
                            migracionId = new MigracionIds();
                            migracionId.NombreTabla = entity;
                            migracionId.IdApStr = id;
                            migracionId.IdSAEGuid = Guid.NewGuid();
                            ctxPeOnline.MigracionIds.AddObject(migracionId);
                            ctxPeOnline.SaveChanges();
                        }
                    }

                    StoreGuidInCache(entity, cacheKey, migracionId.IdSAEGuid.Value);
                    return migracionId.IdSAEGuid.Value;
                }
            }
        }

        public bool PuedoCrearEntity(string entity, string id)
        {
            bool puedo = true;

            if (modoProduccion)
            {
                if (entity != tLegislacion &&
                   entity != tJurisSumario &&
                    entity != tJurisFallo &&
                    entity != tDoctrinaSumario &&
                    entity != tObraCuerpo &&
                    entity != tObra
                    )
                {
                    throw new Exception(string.Format("No se puede crear el Id {1} para {0} en modo produccion", entity, id));
                }
            }

            return puedo;
        }

        public string GetStringIdForApEntity(string entity, int id)
        {
            using (PE_ONLINE_PRODUCCIONEntities ctxPeOnline = new PE_ONLINE_PRODUCCIONEntities())
            {
                MigracionIds migracionId = ctxPeOnline.MigracionIds.Where(m => m.NombreTabla == entity && m.IdApInt == id).SingleOrDefault();
                if (migracionId == null)
                {
                    // Si es nulo lo creo
                    if (PuedoCrearEntity(entity, id.ToString()))
                    {
                        migracionId = new MigracionIds();
                        migracionId.NombreTabla = entity;
                        migracionId.IdApInt = id;
                        migracionId.IdSAEOtro = Guid.NewGuid().ToString();
                        ctxPeOnline.MigracionIds.AddObject(migracionId);
                        ctxPeOnline.SaveChanges();
                    }
                }

                return migracionId.IdSAEOtro;
            }
        }

        public string GetStringIdForApEntity(string entity, string id)
        {
            using (PE_ONLINE_PRODUCCIONEntities ctxPeOnline = new PE_ONLINE_PRODUCCIONEntities())
            {
                MigracionIds migracionId = ctxPeOnline.MigracionIds.Where(m => m.NombreTabla == entity && m.IdApStr == id).SingleOrDefault();
                if (migracionId == null)
                {
                    // Si es nulo lo creo
                    if (PuedoCrearEntity(entity, id))
                    {
                        migracionId = new MigracionIds();
                        migracionId.NombreTabla = entity;
                        migracionId.IdApStr = id;
                        migracionId.IdSAEOtro = Guid.NewGuid().ToString();
                        ctxPeOnline.MigracionIds.AddObject(migracionId);
                        ctxPeOnline.SaveChanges();
                    }
                }

                return migracionId.IdSAEOtro;
            }
        }

        public string GetDocumentoEstadoEnviarNovus(int documentoEstadoId)
        {
            string estado = string.Empty;
            ///1	EN_PROCESO	Documento en base aun no bajado
            ///2	BAJADO_LOCALMENTE	Documento bajado localmente, no pasado a produccion
            ///3	EN_PRODUCCION	Documento ya bajado al repositorio
            ///4	CANCELADO	Documento en el que se interrumpio su procesamiento
            ///
            //    <!--INFORMAR: "ENVIAR" O "NO ENVIAR" 
            //Falta definir con que lógica se informa este valor 
            //si se realizará un mapeo con la tabla 
            //tDocumentoEstado:  	EN_PROCESO -> "NO ENVIAR"??
            //                    BAJADO_LOCALMENTE -> "NO ENVIAR" ??
            //                    EN_PRODUCCION -> "ENVIAR"
            //                    CANCELADO -> "NO ENVIAR"??

            switch (documentoEstadoId)
            {
                case 1:
                case 2:
                case 4:
                    estado = "NO ENVIAR";
                    break;
                case 3:
                    estado = "ENVIAR";
                    break;
            }

            return estado;
        }
    }
}
